/*
 * Copyright (C) 2022 Huawei Technologies Co., Ltd.
 * Licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#ifndef __TEE_DEFINES_H
#define __TEE_DEFINES_H

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>

#ifndef TA_EXPORT
#define TA_EXPORT
#endif

typedef int *tee_mutex_handle;

#define API_LEVEL1_1_1 2
#define API_LEVEL1_2   3

#define TEE_PARAMS_NUM 4
#undef true
#define true 1

#undef false
#define false 0

#ifndef NULL
#define NULL ((void *)0)
#endif

#define PARAM_NOT_USED(val) ((void)val)

typedef union {
    struct {
        void *buffer;
        size_t size;
    } memref;
    struct {
        unsigned int a;
        unsigned int b;
    } value;
    struct {
        void *buffer;
        size_t size;
    } sharedmem;
} TEE_Param;

#define TEE_PARAM_TYPES(param0Type, param1Type, param2Type, param3Type) \
    (((param3Type) << 12) | ((param2Type) << 8) | ((param1Type) << 4) | (param0Type))

#define TEE_PARAM_TYPE_GET(paramTypes, index) (((paramTypes) >> (4U * (index))) & 0x0F)

/*
 * @brief Checks parameter types.
 *
 * @param param_to_check Indicates the expected parameter values.
 * @param valid0 Indicates the first parameter type to check.
 * @param valid1 Indicates the second parameter type to check.
 * @param valid2 Indicates the third parameter type to check.
 * @param valid3 Indicates the fourth parameter type to check.
 *
 * @retval Returns <b>true</b> if the parameter types are correct.
 * @retval Returns <b>false</b> otherwise.
 */
static inline bool check_param_type(uint32_t param_to_check, uint32_t valid0, uint32_t valid1, uint32_t valid2,
                                    uint32_t valid3)
{
    return (TEE_PARAM_TYPES(valid0, valid1, valid2, valid3) == param_to_check);
}

enum TEE_ParamType {
    TEE_PARAM_TYPE_NONE             = 0x0,
    TEE_PARAM_TYPE_VALUE_INPUT      = 0x1,
    TEE_PARAM_TYPE_VALUE_OUTPUT     = 0x2,
    TEE_PARAM_TYPE_VALUE_INOUT      = 0x3,
    TEE_PARAM_TYPE_MEMREF_INPUT     = 0x5,
    TEE_PARAM_TYPE_MEMREF_OUTPUT    = 0x6,
    TEE_PARAM_TYPE_MEMREF_INOUT     = 0x7,
    TEE_PARAM_TYPE_ION_INPUT        = 0x8,
    TEE_PARAM_TYPE_ION_SGLIST_INPUT = 0x9,
    TEE_PARAM_TYPE_MEMREF_SHARED_INOUT = 0xa,
    TEE_PARAM_TYPE_RESMEM_INPUT        = 0xc,
    TEE_PARAM_TYPE_RESMEM_OUTPUT       = 0xd,
    TEE_PARAM_TYPE_RESMEM_INOUT        = 0xe,
};

#define S_VAR_NOT_USED(variable) \
    do {                         \
        (void)(variable);        \
    } while (0);

typedef struct {
    uint32_t objectType;
    uint32_t objectSize;
    uint32_t maxObjectSize;
    uint32_t objectUsage;
    uint32_t dataSize;
    uint32_t dataPosition;
    uint32_t handleFlags;
} TEE_ObjectInfo;

typedef struct {
    uint32_t attributeID;
    union {
        struct {
            void *buffer;
            size_t length;
        } ref;
        struct {
            uint32_t a;
            uint32_t b;
        } value;
    } content;
} TEE_Attribute;

enum TEE_ObjectAttribute {
    TEE_ATTR_SECRET_VALUE          = 0xC0000000,
    TEE_ATTR_RSA_MODULUS           = 0xD0000130,
    TEE_ATTR_RSA_PUBLIC_EXPONENT   = 0xD0000230,
    TEE_ATTR_RSA_PRIVATE_EXPONENT  = 0xC0000330,
    TEE_ATTR_RSA_PRIME1            = 0xC0000430,
    TEE_ATTR_RSA_PRIME2            = 0xC0000530,
    TEE_ATTR_RSA_EXPONENT1         = 0xC0000630,
    TEE_ATTR_RSA_EXPONENT2         = 0xC0000730,
    TEE_ATTR_RSA_COEFFICIENT       = 0xC0000830,
    TEE_ATTR_RSA_MGF1_HASH         = 0xF0000830,
    TEE_ATTR_DSA_PRIME             = 0xD0001031,
    TEE_ATTR_DSA_SUBPRIME          = 0xD0001131,
    TEE_ATTR_DSA_BASE              = 0xD0001231,
    TEE_ATTR_DSA_PUBLIC_VALUE      = 0xD0000131,
    TEE_ATTR_DSA_PRIVATE_VALUE     = 0xC0000231,
    TEE_ATTR_DH_PRIME              = 0xD0001032,
    TEE_ATTR_DH_SUBPRIME           = 0xD0001132,
    TEE_ATTR_DH_BASE               = 0xD0001232,
    TEE_ATTR_DH_X_BITS             = 0xF0001332,
    TEE_ATTR_DH_PUBLIC_VALUE       = 0xD0000132,
    TEE_ATTR_DH_PRIVATE_VALUE      = 0xC0000232,
    TEE_ATTR_RSA_OAEP_LABEL        = 0xD0000930,
    TEE_ATTR_RSA_PSS_SALT_LENGTH   = 0xF0000A30,
    TEE_ATTR_ECC_PUBLIC_VALUE_X    = 0xD0000141,
    TEE_ATTR_ECC_PUBLIC_VALUE_Y    = 0xD0000241,
    TEE_ATTR_ECC_PRIVATE_VALUE     = 0xC0000341,
    TEE_ATTR_ECC_CURVE             = 0xF0000441,
    TEE_ATTR_ED25519_CTX           = 0xD0000643,
    TEE_ATTR_ED25519_PUBLIC_VALUE  = 0xD0000743,
    TEE_ATTR_ED25519_PRIVATE_VALUE = 0xC0000843,
    TEE_ATTR_ED25519_PH            = 0xF0000543,
    TEE_ATTR_X25519_PUBLIC_VALUE   = 0xD0000944,
    TEE_ATTR_X25519_PRIVATE_VALUE  = 0xC0000A44,
    TEE_ATTR_PBKDF2_HMAC_PASSWORD  = 0xD0000133,
    TEE_ATTR_PBKDF2_HMAC_SALT      = 0xD0000134,
    TEE_ATTR_PBKDF2_HMAC_DIGEST    = 0xF0000135,
};

enum TEE_ObjectType {
    TEE_TYPE_AES                = 0xA0000010,
    TEE_TYPE_DES                = 0xA0000011,
    TEE_TYPE_DES3               = 0xA0000013,
    TEE_TYPE_HMAC_MD5           = 0xA0000001,
    TEE_TYPE_HMAC_SHA1          = 0xA0000002,
    TEE_TYPE_HMAC_SHA224        = 0xA0000003,
    TEE_TYPE_HMAC_SHA256        = 0xA0000004,
    TEE_TYPE_HMAC_SHA384        = 0xA0000005,
    TEE_TYPE_HMAC_SHA512        = 0xA0000006,
    TEE_TYPE_RSA_PUBLIC_KEY     = 0xA0000030,
    TEE_TYPE_RSA_KEYPAIR        = 0xA1000030,
    TEE_TYPE_DSA_PUBLIC_KEY     = 0xA0000031,
    TEE_TYPE_DSA_KEYPAIR        = 0xA1000031,
    TEE_TYPE_DH_KEYPAIR         = 0xA1000032,
    TEE_TYPE_GENERIC_SECRET     = 0xA0000000,
    TEE_TYPE_DATA               = 0xA1000033,
    TEE_TYPE_DATA_GP1_1         = 0xA00000BF,
    TEE_TYPE_ECDSA_PUBLIC_KEY   = 0xA0000041,
    TEE_TYPE_ECDSA_KEYPAIR      = 0xA1000041,
    TEE_TYPE_ECDH_PUBLIC_KEY    = 0xA0000042,
    TEE_TYPE_ECDH_KEYPAIR       = 0xA1000042,
    TEE_TYPE_ED25519_PUBLIC_KEY = 0xA0000043,
    TEE_TYPE_ED25519_KEYPAIR    = 0xA1000043,
    TEE_TYPE_X25519_PUBLIC_KEY  = 0xA0000044,
    TEE_TYPE_X25519_KEYPAIR     = 0xA1000044,
    TEE_TYPE_SM2_DSA_PUBLIC_KEY = 0xA0000045,
    TEE_TYPE_SM2_DSA_KEYPAIR    = 0xA1000045,
    TEE_TYPE_SM2_KEP_PUBLIC_KEY = 0xA0000046,
    TEE_TYPE_SM2_KEP_KEYPAIR    = 0xA1000046,
    TEE_TYPE_SM2_PKE_PUBLIC_KEY = 0xA0000047,
    TEE_TYPE_SM2_PKE_KEYPAIR    = 0xA1000047,
    TEE_TYPE_HMAC_SM3           = 0xA0000007,
    TEE_TYPE_SM4                = 0xA0000014,
#ifdef CONFIG_CRYPTO_SUPPORT_SIPHASH
    TEE_TYPE_SIP_HASH           = 0xF0000002,
#endif
    TEE_TYPE_PBKDF2_HMAC        = 0xF0000004,

    TEE_TYPE_CORRUPTED_OBJECT = 0xA00000BE,
};

#define OBJECT_NAME_LEN_MAX 255

struct __TEE_ObjectHandle {
    void *dataPtr;
    uint32_t dataLen;
    uint8_t dataName[OBJECT_NAME_LEN_MAX];
    TEE_ObjectInfo *ObjectInfo;
    TEE_Attribute *Attribute;
    uint32_t attributesLen;
    uint32_t CRTMode;
    void *infoattrfd;
    uint32_t generate_flag;
    uint32_t storage_id;
};
typedef struct __TEE_ObjectHandle *TEE_ObjectHandle;

#define NODE_LEN 8
typedef struct tee_uuid {
    uint32_t timeLow;
    uint16_t timeMid;
    uint16_t timeHiAndVersion;
    uint8_t clockSeqAndNode[NODE_LEN];
} TEE_UUID;

typedef struct spawn_uuid {
    uint64_t uuid_valid;
    TEE_UUID uuid;
} spawn_uuid_t;

enum TEE_Result_Value {
    TEE_SUCCESS                        = 0x00000000, /* The operation is successful.                                 */
    TEE_ERROR_INVALID_CMD              = 0x00000001, /* The command is invalid.                                      */
    TEE_ERROR_SERVICE_NOT_EXIST        = 0x00000002, /* The service does not exist.                                  */
    TEE_ERROR_SESSION_NOT_EXIST        = 0x00000003, /* The session does not exist.                                  */
    TEE_ERROR_SESSION_MAXIMUM          = 0x00000004, /* The number of sessions exceeds the limit.                    */
    TEE_ERROR_REGISTER_EXIST_SERVICE   = 0x00000005, /* The service has been already registered.                     */
    TEE_ERROR_TARGET_DEAD_FATAL        = 0x00000006, /* An internal error occurs.                                    */
    TEE_ERROR_READ_DATA                = 0x00000007, /* Failed to read data.                                         */
    TEE_ERROR_WRITE_DATA               = 0x00000008, /* Failed to write data.                                        */
    TEE_ERROR_TRUNCATE_OBJECT          = 0x00000009, /* Failed to truncate data.                                     */
    TEE_ERROR_SEEK_DATA                = 0x0000000A, /* Failed to seek data.                                         */
    TEE_ERROR_SYNC_DATA                = 0x0000000B, /* Failed to synchronize data.                                  */
    TEE_ERROR_RENAME_OBJECT            = 0x0000000C, /* Failed to rename the file.                                   */
    TEE_ERROR_TRUSTED_APP_LOAD_ERROR   = 0x0000000D, /* An error occurs when the TA is loaded.                       */
    TEE_ERROR_STORAGE_EIO              = 0x80001001, /* An I/O error occurs when data is stored.                     */
    TEE_ERROR_STORAGE_EAGAIN           = 0x80001002, /* The storage section is unavailable.                          */
    TEE_ERROR_STORAGE_ENOTDIR          = 0x80001003, /* The operation target is not a directory.                     */
    TEE_ERROR_STORAGE_EISDIR           = 0x80001004, /* This operation cannot be performed on a directory.           */
    TEE_ERROR_STORAGE_ENFILE           = 0x80001005, /* The number of opened files exceeds the limit in system.      */
    TEE_ERROR_STORAGE_EMFILE           = 0x80001006, /* The number of files opened for the process exceeds the limit.*/
    TEE_ERROR_STORAGE_EROFS            = 0x80001007, /* The storage section is read only.                            */
    TEE_ERROR_STORAGE_PATH_WRONG       = 0x8000100A, /* The file path is not correct.                                */
    TEE_ERROR_MSG_QUEUE_OVERFLOW       = 0x8000100B, /* The service message queue overflows.                         */
    TEE_ERROR_CORRUPT_OBJECT           = 0xF0100001, /* The file object is corrupted.                                */
    TEE_ERROR_STORAGE_NOT_AVAILABLE    = 0xF0100003, /* The storage section is unavailable.                          */
    TEE_ERROR_CIPHERTEXT_INVALID       = 0xF0100006, /* The cipher text is incorrect.                                */
    TEE_ISOCKET_ERROR_PROTOCOL         = 0xF1007001, /* Protocol error in socket connection.                         */
    TEE_ISOCKET_ERROR_REMOTE_CLOSED    = 0xF1007002, /* The socket is closed by the remote end.                      */
    TEE_ISOCKET_ERROR_TIMEOUT          = 0xF1007003, /* The socket connection timed out.                             */
    TEE_ISOCKET_ERROR_OUT_OF_RESOURCES = 0xF1007004, /* There is no resource available for the socket connection.    */
    TEE_ISOCKET_ERROR_LARGE_BUFFER     = 0xF1007005, /* The buffer is too large for the socket connection.           */
    TEE_ISOCKET_WARNING_PROTOCOL       = 0xF1007006, /* A warning is given in the socket connection.                 */
    TEE_ERROR_GENERIC                  = 0xFFFF0000, /* Generic error.                                               */
    TEE_ERROR_ACCESS_DENIED            = 0xFFFF0001, /* The access is denied.                                        */
    TEE_ERROR_CANCEL                   = 0xFFFF0002, /* The operation has been canceled.                             */
    TEE_ERROR_ACCESS_CONFLICT          = 0xFFFF0003, /* An access conflict occurs.                                   */
    TEE_ERROR_EXCESS_DATA              = 0xFFFF0004, /* The data size exceeds the maximum.                           */
    TEE_ERROR_BAD_FORMAT               = 0xFFFF0005, /* Incorrect data format.                                       */
    TEE_ERROR_BAD_PARAMETERS           = 0xFFFF0006, /* Incorrect parameters.                                        */
    TEE_ERROR_BAD_STATE                = 0xFFFF0007, /* The current state does not support the operation.            */
    TEE_ERROR_ITEM_NOT_FOUND           = 0xFFFF0008, /* Failed to find the target item.                              */
    TEE_ERROR_NOT_IMPLEMENTED          = 0xFFFF0009, /* The API is not implemented.                                  */
    TEE_ERROR_NOT_SUPPORTED            = 0xFFFF000A, /* The API is not supported.                                    */
    TEE_ERROR_NO_DATA                  = 0xFFFF000B, /* There is no data available for this operation.               */
    TEE_ERROR_OUT_OF_MEMORY            = 0xFFFF000C, /* There is no memory available for this operation.             */
    TEE_ERROR_BUSY                     = 0xFFFF000D, /* The system does not respond to this operation.               */
    TEE_ERROR_COMMUNICATION            = 0xFFFF000E, /* Failed to communicate with the target.                       */
    TEE_ERROR_SECURITY                 = 0xFFFF000F, /* A security error occurs.                                     */
    TEE_ERROR_SHORT_BUFFER             = 0xFFFF0010, /* The buffer is insufficient for this operation.               */
    TEE_ERROR_EXTERNAL_CANCEL          = 0xFFFF0011, /* The operation has been canceled.                             */
    TEE_PENDING                        = 0xFFFF2000, /* The service is in the pending state (asynchronous state).    */
    TEE_PENDING2                       = 0xFFFF2001, /* The service is in the pending state().                       */
    TEE_PENDING3                       = 0xFFFF2002, /* Reserved.                                                    */
    TEE_ERROR_TIMEOUT                  = 0xFFFF3001, /* The operation timed out.                                     */
    TEE_ERROR_OVERFLOW                 = 0xFFFF300f, /* Overflow occurs.                                             */
    TEE_ERROR_TARGET_DEAD              = 0xFFFF3024, /* The TA is crashed.                                           */
    TEE_ERROR_STORAGE_NO_SPACE         = 0xFFFF3041, /* There is no enough space to store data.                      */
    TEE_ERROR_MAC_INVALID              = 0xFFFF3071, /* The MAC operation failed.                                    */
    TEE_ERROR_SIGNATURE_INVALID        = 0xFFFF3072, /* The signature verification failed.                           */
    TEE_CLIENT_INTR                    = 0xFFFF4000, /* Interrupted by CFC. Broken control flow is detected.         */
    TEE_ERROR_TIME_NOT_SET             = 0xFFFF5000, /* Time is not set.                                             */
    TEE_ERROR_TIME_NEEDS_RESET         = 0xFFFF5001, /* Time needs to be reset.                                      */
    TEE_FAIL                           = 0xFFFF5002, /* System error.                                                */
    TEE_ERROR_TIMER                    = 0xFFFF6000, /* Base value of the timer error code.                          */
    TEE_ERROR_TIMER_CREATE_FAILED      = 0xFFFF6001, /* Failed to create the timer.                                  */
    TEE_ERROR_TIMER_DESTORY_FAILED     = 0xFFFF6002, /* Failed to destroy the timer.                                 */
    TEE_ERROR_TIMER_NOT_FOUND          = 0xFFFF6003, /* The timer is not found.                                      */
    TEE_ERROR_SEC_FLASH_NOT_AVAILABLE  = 0xFFFF7118, /* sec flash is not available.                                  */
    TEE_ERROR_BIOSRV_NOT_AVAILABLE     = 0xFFFF711A, /* The BIO service is not available.                            */
    TEE_ERROR_ROTSRV_NOT_AVAILABLE     = 0xFFFF711B, /* The ROT service is not available.                            */
    TEE_ERROR_ARTSRV_NOT_AVAILABLE     = 0xFFFF711C, /* The ART service is not available.                            */
    TEE_ERROR_HSMSRV_NOT_AVAILABLE     = 0xFFFF711D, /* The HSM service is not available.                            */
    TEE_ERROR_ANTIROOT_RSP_FAIL        = 0xFFFF9110, /* Failed to verify AntiRoot response.                          */
    TEE_ERROR_ANTIROOT_INVOKE_ERROR    = 0xFFFF9111, /* AntiRoot error in invokeCmd().                               */
    TEE_ERROR_AUDIT_FAIL               = 0xFFFF9112, /* Audit failed.                                                */
    TEE_FAIL2                          = 0xFFFF9113  /* Unused.                                                      */
};

/*
 * Login type definitions
 */
enum TEE_LoginMethod {
    TEE_LOGIN_PUBLIC = 0x0,
    TEE_LOGIN_USER,
    TEE_LOGIN_GROUP,
    TEE_LOGIN_APPLICATION      = 0x4,
    TEE_LOGIN_USER_APPLICATION = 0x5,
    TEE_LOGIN_GROUP_APPLICATION = 0x6,
    TEE_LOGIN_IDENTIFY = 0x7, /* Customized login type */
};

typedef struct {
    uint32_t login;
    TEE_UUID uuid;
} TEE_Identity;

typedef uint32_t TEE_Result;
typedef TEE_Result TEEC_Result;

#define TEE_ORIGIN_TEE             0x00000003
#define TEE_ORIGIN_TRUSTED_APP     0x00000004

#ifndef _TEE_TA_SESSION_HANDLE
#define _TEE_TA_SESSION_HANDLE
typedef uint32_t TEE_TASessionHandle;
#endif

typedef struct __TEE_ObjectHandle *TEE_ObjectHandle;
typedef struct __TEE_ObjectEnumHandle *TEE_ObjectEnumHandle;
typedef struct __TEE_OperationHandle *TEE_OperationHandle;

#define TEE_TIMEOUT_INFINITE (0xFFFFFFFF)

typedef struct {
    uint32_t seconds;
    uint32_t millis;
} TEE_Time;

typedef struct {
    int32_t seconds;
    int32_t millis;
    int32_t min;
    int32_t hour;
    int32_t day;
    int32_t month;
    int32_t year;
} TEE_Date_Time;

typedef struct {
    uint32_t type;
    uint32_t timer_id;
    uint32_t timer_class;
    uint32_t reserved2;
} TEE_timer_property;

#endif
